package General;

	public class Wallet {
		final int MAX_VAL=5;
		/**
		 * resources are immutable 
		 */
		Resource myResources;
		/**
		 * Initialize an empty wallet
		 */
		public Wallet(){
			myResources = new Resource();
		}
		public Wallet(Resource res){
			myResources = res;	//resources is immutable so this assignment is OK;
		}
		/**
		 * It would be possible to put spoilage in the resources where it calculates the payment cost
		 * spoilage is implemented in Wallet, as we need conservation of resources, which is outside the scope of Resource
		 * victory points do not spoil
		 */
		public void spoilage(){	
			//TODO pay each overfilled resource
			int[] current = new int[4];
			int[] payment = new int[4];
			current[0] 	= myResources.getFood();
			current[1]	= myResources.getWood();
			current[2]	= myResources.getFavor();
			current[3]	= myResources.getGold();
			
			for(int i = 0; i<4; i++){
				if (current[i] >MAX_VAL){
					payment[i] = current[i] -MAX_VAL;
				} else{
					payment[i] = 0;
				}
			}
			pay(new Resource(payment[0],payment[1],payment[2],payment[3],0),Bank.singletonBank.getWallet());
			//TODO coupling between Wallet and Bank occurs here
		}
		public boolean pay(Resource cost, Wallet target){
			if(!myResources.creditCheck(cost))	return false;	//if you can't pay, refuse transaction
			myResources = myResources.subtractResource(cost);	//remove the resources from this wallet
			target.receive(cost);								//place the resources in the recipient's wallet
			return true;
		}
		public void receive(Resource payment){
			myResources = myResources.addResource(payment);
		}
		
		//bank only code, should probably expand to use polymorphism if this section expands
		public void forcePay(Resource cost, Wallet target){
			if(myResources.creditCheck(cost)){
				pay(cost, target);
			} else{
				pay(new Resource(
						(myResources.getFood() < cost.getFood())?cost.getFood():myResources.getFood(),
						(myResources.getWood() < cost.getWood())?cost.getWood():myResources.getWood(),
						(myResources.getFavor() < cost.getFavor())?cost.getFavor():myResources.getFavor(),
						(myResources.getGold() < cost.getGold())?cost.getGold():myResources.getGold()),
						//(myResources.getVictory() < cost.getVictory())?cost.getVictory():myResources.getVictory()),
						target);
			}
			//Bank always uses this method
			//Same as pay but allow transaction if insufficient funds.  Simply pay what is available
			//When the bank runs low on resources it will still transact, just not the full amount
		}
		public Resource getFunds(){
			return myResources;	//Resource are immutable so no copy needed
		}
}
